from PyQt4.QtCore import SIGNAL

from hashlib import md5
import time

from network.baseDriver import BaseDriver


def get_time():
     return int(time.time()) % 1e6


def encode_bool(val):
    if val:
        return 1
    else:
        return 0


def encode_password(password):
    salt_head = 'Chain For Perls'
    salt_end = 'Should we replace Perls for Pearls?'
    m = md5()
    code = salt_head + password + salt_end
    for i in range(16):
        m.update(code)
        code = m.hexdigest()
    return code[0:20]


class UserDriver(BaseDriver):
    # all boolean will be replaced for 0-1 only in this class
    def __init__(self, parent=None):
        super(UserDriver, self).__init__(parent)
        # data
        self.self_name = ''
        self.self_success = 0
        self.self_failure = 0
        self.self_score = 0
        self.self_ready = 0
        self.online = False
        self.partner_name = ''
        self.has_partner = 0
        self.partner_success = 0
        self.partner_failure = 0
        self.partner_score = 0
        self.partner_ready = 0

    def timerEvent(self, event):
        if self.online:
            self.flush_partner()

    def login(self, username, password):
        # print(password)
        password_code = encode_password(password)
        values = {
            'username': username,
            'password': password_code,
            'time': get_time()
        }
        response = self.doRequest('/login/', values)
        if response['username'] == username:
            self.self_name = response['username']
            self.self_success = response['success']
            self.self_failure = response['failure']
            self.self_score = response['score']
            self.online = True
            self.emit(SIGNAL('login_succeed()'))
        else:
            self.emit(SIGNAL('login_failed()'))

    def logout(self):
        self.online = False
        values = {
            "username": self.self_name,
            "time": get_time()
        }
        response = self.doRequest('/sign_out/', values)

    def signUp(self, username, password, email):
        password_code = encode_password(password)
        print(password_code)
        values = {
            'username': username,
            'password': password_code,
            'email': email,
            'time': get_time()
        }
        response = self.doRequest('/signup/', values)
        res_username = response['username']
        if res_username != username or res_username == '_existed':
            self.emit(SIGNAL('sign_up_failed()'))
        else:
            self.emit(SIGNAL('sign_up_succeed()'))

    def resetPassword(self, username, password, newPassword):
        # print(password)
        password_code = encode_password(password)
        new_password_code = encode_password(newPassword)
        values = {
            'username': username,
            'old_password': password_code,
            'time': get_time(),
            'new_password': new_password_code
        }
        response = self.doRequest('/reset_password/', values)
        if response['result'] == 'ok':
            self.emit(SIGNAL('reset_password_result(int)'), 0)
        elif response['result'] == '_invalid_password':
            self.emit(SIGNAL('reset_password_result(int)'), 1)

    def ready(self, ready_argu):
        ready = encode_bool(ready_argu)
        self.self_ready = ready
        values = {
            'username': self.self_name,
            'time': get_time(),
            'ready': ready
        }
        response = self.doRequest('/ready/', values)

    def change(self):
        values = {
            'username': self.self_name,
            'time': get_time()
        }
        response = self.doRequest('/change/', values)
        self.partner_name = response['name']
        if self.partner_name == '_none':
            return
        self.partner_success = response['success']
        self.partner_failure = response['failure']
        self.partner_score = response['score']
        self.partner_ready = 0
        self.has_partner = 1
        self.emit(SIGNAL('partner_changed()'))

    def flush_partner(self):
        values = {
            'username': self.self_name,
            'has_partner': self.has_partner,
            'partner_ready': self.partner_ready,
            'time': get_time()
        }
        response = self.doRequest('/flush_partner/', values)
        action_type = response['action_type']
        if action_type == 'nothing':
            return
        elif action_type == 'partner_ready':
            self.online = False
            self.partner_ready = response['partner_ready']
            self.emit(SIGNAL('partner_ready(int)'), self.partner_ready)
        elif action_type == 'game_start':
            self.online = False
            role = response['role']
            self.emit(SIGNAL('game_start(int)'), role)
        elif action_type == 'partner_changed':
            self.online = False
            self.partner_name = response['name']
            if self.partner_name != '_none':
                self.partner_success = response['success']
                self.partner_failure = response['failure']
                self.partner_score = response['score']
                self.partner_ready = 0
                self.has_partner = 1
            else:
                self.partner_success = 0
                self.partner_failure = 0
                self.partner_score = 0
                self.partner_ready = 0
                self.has_partner = 0
            self.emit(SIGNAL('partner_changed()'))

